#pragma once

namespace SD_Tools
{
	struct KeyState
	{
		BYTE LastState;
		DWORD LastTime;
		bool KeyHold;
	};

	class DInput8Wrapper
	{
	private:
		int PressTime;
		int HoldPressTime;
		KeyState KeyStates[256];

	public:

	private:

	public:
		DInput8Wrapper(int PressTime, int HoldPressTime);
		void Update(BYTE* Array, BYTE* Out);
		void SetPressTime(int PressTime);
		int* GetPressTimePtr();
		int* GetPressHoldTimePtr();
		int GetPressTime();
	};

	//************************************
	// Method:    DInput8Wrapper
	// Profit:	  Creates A DInput8Wrapper Object
	// FullName:  SD_Tools::DInput8Wrapper::DInput8Wrapper
	// Returns:   
	// Notes:
	// -None
	//************************************
	DInput8Wrapper::DInput8Wrapper( int PressTime, int HoldPressTime )
	{
		this->PressTime = PressTime;
		this->HoldPressTime = HoldPressTime;
		memset(KeyStates, 0, sizeof(KeyStates));
	}

	//************************************
	// Method:    Update
	// Profit:	  Updates The Wrapper
	// FullName:  SD_Tools::DInput8Wrapper::Update
	// Returns:   void
	// Notes:
	// -OutArray will receive the Pressed Keys
	// -In and OutArray have to be 256 BYTE values for each key
	//************************************
	void DInput8Wrapper::Update( BYTE* Array, BYTE* Out )
	{
		DWORD ActualTime = GetTickCount();
		memset(Out, 0, 256);

		for (int i = 0; i < 256; i++)
		{
			if (KeyStates[i].LastState != Array[i])
			{
				if (Array[i] & (1<<7))
				{
					KeyStates[i].LastTime = ActualTime;
					KeyStates[i].KeyHold = false;
					Out[i] = 1;
				}
				KeyStates[i].LastState = Array[i];
			}
			else
			{
				if (Array[i] & (1<<7))
				{
					if (KeyStates[i].KeyHold)
					{
						if (KeyStates[i].LastTime + HoldPressTime < ActualTime)
						{
							KeyStates[i].LastTime = ActualTime;
							Out[i] = 1;
						}
					}
					else if (KeyStates[i].LastTime + PressTime < ActualTime)
					{
						KeyStates[i].KeyHold = true;
						KeyStates[i].LastTime = ActualTime;
						Out[i] = 1;
					}
				}
			}
		}
	}

	//************************************
	// Method:    SetPressTime
	// Profit:	  Sets the PressTime
	// FullName:  SD_Tools::DInput8Wrapper::SetPressTime
	// Returns:   void
	// Notes:
	// -None
	//************************************
	void DInput8Wrapper::SetPressTime( int PressTime )
	{
		this->PressTime = PressTime;
	}

	//************************************
	// Method:    GetPressTimePtr
	// Profit:	  Returns a Pointer to the PressTime
	// FullName:  SD_Tools::DInput8Wrapper::GetPressTimePtr
	// Returns:   int*
	// Notes:
	// -This function actually destroys the encapsulation
	//************************************
	int* DInput8Wrapper::GetPressTimePtr()
	{
		return &this->PressTime;
	}

	//************************************
	// Method:    GetPressHoldTimePtr
	// Profit:	  Returns a Pointer the HoldTime
	// FullName:  SD_Tools::DInput8Wrapper::GetPressHoldTimePtr
	// Returns:   int*
	// Notes:
	// -This function actually destroys the encapsulation
	//************************************
	int* DInput8Wrapper::GetPressHoldTimePtr()
	{
		return &this->HoldPressTime;
	}

	//************************************
	// Method:    GetPressTime
	// Profit:	  Returns the PressTime
	// FullName:  SD_Tools::DInput8Wrapper::GetPressTime
	// Returns:   int
	// Notes:
	// -None
	//************************************
	int DInput8Wrapper::GetPressTime()
	{
		return this->PressTime;
	}

};










